import pymysql
import pandas as pd
import asyncio
import time
import datetime
import traceback
import os
import sys
import numpy as np
import pytz
# print(os.path.join(os.path.split(os.path.split(sys.path[0])[0])[0], "bin"))
# # 添加导包路径
# sys.path.append(os.path.join(os.path.split(os.path.split(sys.path[0])[0])[0], "bin"))
sys.path.append(r"D:\my_work\ac_lingxing_api\ac_lingxing_api")
from multiprocessing import  Process, Queue, Pool
from bin.openapi import OpenApiBase
from sqlalchemy import create_engine
from itertools import product
from itertools import islice
from lxml import etree
import re
import demoji



class tools:
    
    @staticmethod
    def chunked_iterable(iterable, size):
        it = iter(iterable)
        return iter(lambda: tuple(islice(it, size)), ())
    
    
    @staticmethod
    def get_engine():
        engine = create_engine('mysql+pymysql://user_rpa:123456@192.168.8.10:3306/rpa?charset=utf8mb4')
        return engine
    
    @staticmethod
    def get_app_token():
        engine = tools.get_engine()
        res = pd.read_sql("select appId, appSecret from lx_app_token", con=engine)
        app_id_lst = []
        app_secret_lst = []
        for i, data in res.iterrows():
            app_id_lst.append(data['appId'])
            app_secret_lst.append(data['appSecret'])
        return app_id_lst, app_secret_lst

    @staticmethod
    def get_order_id():
        query = "select distinct order_num from lx_cus_service_detail where is_update_state = 0"
        engine = tools.get_engine()
        query_df = pd.read_sql(query, con=engine)
        query_lst = list(set(query_df['order_num'].to_list()))
        return query_lst

    @staticmethod
    def update_data(query):
        conn = pymysql.connect(user='user_rpa', password='123456', host='192.168.8.10', database='rpa')
        cur = conn.cursor()
        cur.execute(query)
        conn.commit()
        cur.close()
        conn.close()

    @staticmethod
    def update_detail(webmail_uuid_str):
        query = f"update lx_cus_service set is_get_detail = 1 where webmail_uuid in ({webmail_uuid_str})"
        conn = pymysql.connect(user='user_rpa', password='123456', host='192.168.8.10', database='rpa')
        cur = conn.cursor()
        cur.execute(query)
        conn.commit()
        cur.close()
        conn.close()
        

class lx_api:

    def __init__(self, app_id, app_secret):
        
        self.op_api = OpenApiBase("https://openapi.lingxing.com", app_id, app_secret)
        self.access_token = ""
        self.refresh_token = ""
        self.engine = tools.get_engine()
        self.table_name = "lx_order_detail"
        self.url = "/erp/sc/data/mws/orderDetail"
        

    async def generate_access_token(self):
        resp = await self.op_api.generate_access_token()
        self.access_token = resp.access_token
        self.refresh_token = resp.refresh_token
        assert resp.access_token
        # return resp.dict()
    
    async def refresh_token_handler(self):
        resp = await self.op_api.refresh_token(self.refresh_token)
        self.refresh_token =  resp.refresh_token
        self.access_token = resp.access_token
        assert resp.access_token

    async def check_token(self, data):
        if data['code'] == 0:
            return True
        elif data['code'] in [2001005, 2001003, 2001008, 2001009]:
            await self.generate_access_token()
            return False
        else:
            print(data['code'])
            return False
    
    async def get_email_data(self, order_id):
        req_body = {
            "order_id":order_id
        }
        print(req_body)
        res_lst = []
        while 1:
            try:
                res = await self.op_api.request(self.access_token, self.url, "POST", req_body=req_body)
            except:
                print("异常:", traceback.format_exc())
                time.sleep(1)
                continue
            resp = res.dict()
            if not await self.check_token(resp):
                continue
            if len(resp['data']) != 0:
                res_lst = res_lst + resp['data']
            break
        if len(res_lst) == 0:
            print("无数据")
            return []
        for res_data in res_lst:
            item_list = res_data['item_list']
            del res_data['item_list']
            print("结果值中，item_list的数量",len(item_list))
            item_one = item_list[0]
            res_data.update(item_one)
            
        res_df = pd.DataFrame(res_lst)
        res_df['update_time'] = pd.to_datetime(datetime.datetime.now())
        res_df = res_df.drop(['promotion_ids'], axis=1)
        
        if len(res_df)>0:
            amazon_order_id_lst = res_df['amazon_order_id'].tolist()
            amazon_order_id = ",".join(["'" + amazon_order_id + "'" for amazon_order_id in amazon_order_id_lst])
            query = f"delete from {self.table_name} where amazon_order_id in ({amazon_order_id}) "
            
            tools.update_data(query)
            res_df.to_sql(self.table_name, con=self.engine, if_exists="append", index=False)
            print(f"{order_id} 数据已插入")
        else:
            print("无数据")
    async def hanlder(self, semaphore, order_id):
        async with semaphore:
            await self.get_email_data(order_id)
            
        
    async def main(self, order_id_lst_all):
        semaphore = asyncio.Semaphore(1)
        await self.generate_access_token()
        tasks = []
        print(order_id_lst_all)
        for order_id in order_id_lst_all:
            if order_id:

                tasks.append(asyncio.create_task(self.hanlder(semaphore, order_id)))

        # print(tasks)
        result = await asyncio.gather(*tasks)
            
        
        

def run(app_id, app_secret, order_id_lst_all):
    
    lx_app = lx_api(app_id, app_secret)
    
    
    asyncio.run(lx_app.main(order_id_lst_all))
    
        

def main():
    num = 1
    app_id_lst, app_secret_lst = tools.get_app_token()
    order_id_lst_all = tools.get_order_id()
    order_id_lst_all = np.array_split(order_id_lst_all, num)
    # print(order_id_lst_all)
    
    pool = Pool(num)
    for i in range(num):
        pool.apply_async(func=run, args=(app_id_lst[i], app_secret_lst[i], order_id_lst_all[i]))
    pool.close()
    pool.join()
if __name__ == "__main__":  
    main()